#include "../include/extendedlibparser.h"
double ExtendedLibParser::getMinInputCapacitance ( std::string footprint, std::string pinName)
{
	std::map<std::string, LibParserCellInfo>::iterator libIt ;
	double minCap = 100000.0 ;
	
	for ( libIt = this->mapStandardLibraryCells.begin() ; libIt != this->mapStandardLibraryCells.end() ; ++libIt)
	{
		if (libIt->second.footprint != footprint)
			continue ;
			
		minCap = std::min( minCap, this->getInputCapacitance(libIt->second.name, pinName) ) ;
	}
	
	return minCap ;
} 


/*double ExtendedLibParser::findMaxTransition(std::string cellName, std::string instanceName, ExtendedTimingParser& timing, double outCap)
  {
  std::vector<LibParserTimingInfo>::iterator timingIt ;
	
  double maxTrans = 0.0 ;
	
	
  bool valid ;
	
  for (timingIt = this->mapStandardLibraryCells[cellName].timingArcs.begin() ;
  timingIt != this->mapStandardLibraryCells[cellName].timingArcs.end() ;
  ++timingIt)
  {	
	
  std::string timingStr = instanceName + "/" + timingIt->fromPin ;
		
  double fallInputTrans = timing.PinsTiming[timingStr].fallTransition ;
  double riseInputTrans = timing.PinsTiming[timingStr].riseTransition ;
		
  double maxTimingTrans = std::max( timingIt->fallTransition(outCap, riseInputTrans, valid),
  timingIt->riseTransition(outCap, fallInputTrans, valid) ) ;
		
  if (!valid)
  maxTrans = -1 ;
  else
  maxTrans = std::max(maxTrans, maxTimingTrans) ;
  }
	
	
  return maxTrans ;

  }
*/


int ExtendedLibParser::readStandardLibraryCell()
{
	cout << "Start reading standard cell library"<< endl ;	
	bool valid = (*this).read_default_max_transition ( this->maxTransition ) ;
	assert ( valid ) ;
	cout << "The default max transition defined is: " << maxTransition << endl ;
        
	int readCnt = 0 ;
	do {
	
		LibParserCellInfo cell ;
		valid = (*this).read_cell_info (cell) ;
		
		if (valid && cell.name != "vcc" && cell.name != "vss") {
			
#ifdef DEBUG
                        cout << cell.name << endl ;
#endif
			
			mapStandardLibraryCells[cell.name] = cell ;
			++readCnt ;

		}
		
	} while ( valid ) ;
	
	cout << "Read " << readCnt << " number of library cells." << endl ; 
	return readCnt ;
	
}


inline LibParserCellInfo ExtendedLibParser::getStandardCell (std::string cellName)
{
	return mapStandardLibraryCells[cellName] ;
}


void ExtendedLibParser::findSameFootPrint(std::string footprintName, std::vector<std::string>& fpVector)
{
	fpVector.clear() ;	
	std::map<std::string, LibParserCellInfo>::iterator libraryIt ;
	for (libraryIt = this->mapStandardLibraryCells.begin() ; libraryIt != this->mapStandardLibraryCells.end() ; ++libraryIt)
	{
		if ((*libraryIt).second.footprint == footprintName)
			fpVector.push_back((*libraryIt).second.name) ;
	}
}


std::pair<double, double> ExtendedLibParser::pinCapacitance (std::string footprint, std::string pin)
{
	double minPinCapacitance = std::numeric_limits<double>::max() ;
	double maxPinCapacitance = std::numeric_limits<double>::min() ;
	
	std::vector<std::string>::iterator si ;
	std::vector<LibParserPinInfo>::iterator pi ;
	
	std::vector<std::string> footprintVector ;
	
	this->findSameFootPrint (footprint, footprintVector) ;

	LibParserCellInfo tmpCell ;
	
	for (si = footprintVector.begin() ; si != footprintVector.end() ; ++si)
	{
		tmpCell = this->mapStandardLibraryCells[(*si)] ;

		for (pi = tmpCell.pins.begin() ; pi != tmpCell.pins.end() ; ++pi)
		{
			if ((*pi).name == pin)
			{
                                maxPinCapacitance = std::max( (*pi).capacitance, maxPinCapacitance ) ;
                                minPinCapacitance = std::min( (*pi).capacitance, minPinCapacitance ) ;
			}
		}
	}
	
	return std::make_pair <double, double> (minPinCapacitance, maxPinCapacitance) ;
	
}


void ExtendedLibParser::findCombinations(std::string filename, double wireCap)
{

	std::map<std::string, LibParserCellInfo>::iterator ci ;
	std::ofstream combinationFile (filename.c_str()) ;
	
	double currCellMaxCap = 0.0 ;
	
	std::vector<std::string> legalCells ;
	
	for (ci = this->mapStandardLibraryCells.begin() ; ci != this->mapStandardLibraryCells.end() ; ++ci)
	{
		legalCells.clear() ;
		
		combinationFile << "------------------------------------------" << endl ;
		combinationFile << "Cell Name: \t" << (*ci).second.name << endl ;
		for (int i = 0 ; i < (int) (*ci).second.pins.size() ; ++ i)
			if (!(*ci).second.pins[i].isInput)
				currCellMaxCap = (*ci).second.pins[i].maxCapacitance ;
				
		this->findLegalCombination (currCellMaxCap - wireCap, (*ci).second.name, legalCells) ;
		
		combinationFile << "Number of Cells: " << legalCells.size()  << endl; 
		
		for (int j = 0 ; j < (int) legalCells.size() ; j++)
			combinationFile << legalCells[j] << endl ;
		
	}	
}


void ExtendedLibParser::findLegalCombination (double maxCapacitance, std::string cellName, std::vector<std::string>& legalCells)
{
	std::map<std::string, LibParserCellInfo>::iterator ci ;
	bool valid ;
	for (ci = this->mapStandardLibraryCells.begin() ; ci != this->mapStandardLibraryCells.end() ; ++ci)
	{
		valid = true ;
		if ((*ci).second.name == cellName)
			continue ;
			
		for (int i = 0 ; i < (int) (*ci).second.pins.size() ; ++ i)
		{
			if ((*ci).second.pins[i].isInput)
				if ((*ci).second.pins[i].capacitance > maxCapacitance)
					valid = false ;
		}
		
		if (valid)
			legalCells.push_back ((*ci).second.name) ;
	
	}
}


void ExtendedLibParser::findCapRange (std::string fpName, vector<double>& capVal)
{

#ifdef DEBUG
        cout << "start finding capacitance range" << endl ;
#endif
	
	std::vector<double>::iterator findIt;
	std::vector<double>::iterator curr, curr_end ;
	std::map<std::string, LibParserCellInfo>::iterator ci ;
	
	for (ci = this->mapStandardLibraryCells.begin() ; ci !=  this->mapStandardLibraryCells.end() ; ++ci)
	{
		if ((*ci).second.footprint == fpName)
		{
			
			curr_end = (*ci).second.timingArcs[0].fallDelay.loadIndices.end() ;
			
			for ( curr = (*ci).second.timingArcs[0].fallDelay.loadIndices.begin() ;curr != curr_end ; ++curr)
			{
#ifdef DEBUG
                                cout << "curr:: " << (*curr) << endl ;
#endif
				
				if ( find (capVal.begin(), capVal.end(), (*curr)) != capVal.end() )
					continue ;
					
#ifdef DEBUG
                                cout << "Push:: " << (*curr) << endl ;
#endif
				
				capVal.push_back((*curr)) ;
			}
		}
	}
	
	sort (capVal.begin(), capVal.end()) ;
#ifdef DEBUG
        cout << "end finding capacitance range " << fpName << endl ;
#endif
}


void ExtendedLibParser::findTransRange (std::string fpName, vector<double>& transVal)
{
#ifdef DEBUG
        cout << "Start finding transition range " << fpName << endl ;
#endif

	std::vector<double>::iterator findIt;
	std::vector<double>::iterator curr, curr_end ;
	std::map<std::string, LibParserCellInfo>::iterator ci ;
	
	for (ci = this->mapStandardLibraryCells.begin() ; ci !=  this->mapStandardLibraryCells.end() ; ++ci)
	{
		if ((*ci).second.footprint == fpName)
		{
			
			curr_end = (*ci).second.timingArcs[0].fallDelay.transitionIndices.end() ;
			
			for ( curr = (*ci).second.timingArcs[0].fallDelay.transitionIndices.begin() ;curr != curr_end ; ++curr)
			{
#ifdef DEBUG
                                cout << "curr:: " << (*curr) << endl ;
#endif
				
				if ( find (transVal.begin(), transVal.end(), (*curr)) != transVal.end() )
					continue ;
					
#ifdef DEBUG
                                cout << "Push:: " << (*curr) << endl ;
#endif
				
				transVal.push_back((*curr)) ;
			}
		}
	}
	
	sort (transVal.begin(), transVal.end()) ;
	
#ifdef DEBUG
        cout << "end finding transition range " << fpName << endl ;
#endif

}



double ExtendedLibParser::findMaxOutputCapacitance (std::string cell)
{
	std::vector<LibParserPinInfo>::iterator pinIt ;
	double result ;
	for (pinIt = this->mapStandardLibraryCells[cell].pins.begin() ; pinIt != this->mapStandardLibraryCells[cell].pins.end() ;
             ++pinIt)
	{
		if ((*pinIt).isInput)
			continue ;
		else
		{
			result =  (*pinIt).maxCapacitance ;
			break ;
		}
	}
	return result ;
}


double ExtendedLibParser::maxFallDelay (std::string cellName, std::map<std::string, double>& pinTrans, double outCap, bool& valid)
{
	double maxDelay = 0.0 ;
	
	std::vector<LibParserTimingInfo>::iterator timingIt ;
	
	if (pinTrans.size() != this->mapStandardLibraryCells[cellName].timingArcs.size())
	{
#ifdef DEBUG
                cout << "The number of pin input transition are not equal to the gate pins" << endl ;
#endif
		
		return 0.0 ;
	}
	for (timingIt = this->mapStandardLibraryCells[cellName].timingArcs.begin() ; timingIt != this->mapStandardLibraryCells[cellName].timingArcs.end() ; ++timingIt)
	{
		double inputTrans = pinTrans[(*timingIt).fromPin] ;
		double tmpFallDelay = (*timingIt).fallDelay(outCap, inputTrans, valid) ;
		
		if (!valid)
		{
#ifdef DEBUG
                        cout << "The output capacitance and/or input transition are not in the legal range" << endl ;
#endif
			return 0.0 ;
		}
		else
			maxDelay = std::max (maxDelay, tmpFallDelay) ;
	}
	
	valid = true ;
	return maxDelay ;
}


double ExtendedLibParser::maxRiseDelay (std::string cellName, std::map<std::string, double>& pinTrans, double outCap, bool& valid)
{
	double maxDelay = 0.0 ;
	
	std::vector<LibParserTimingInfo>::iterator timingIt ;
	
	if (pinTrans.size() != this->mapStandardLibraryCells[cellName].timingArcs.size())
	{
#ifdef DEBUG
                cout << "The number of pin input transition are not equal to the gate pins" << endl ;
#endif
		
		return 0.0 ;
	}	
	
	for (timingIt = this->mapStandardLibraryCells[cellName].timingArcs.begin() ; timingIt != this->mapStandardLibraryCells[cellName].timingArcs.end() ; ++timingIt)
	{
		double inputTrans = pinTrans[(*timingIt).fromPin] ;
		double tmpFallDelay = (*timingIt).riseDelay(outCap, inputTrans, valid) ;
		
		if (!valid)
		{
#ifdef DEBUG
                        cout << "The output capacitance and/or input transition are not in the legal range" << endl ;
#endif
			return 0.0 ;
		}
		else
			maxDelay = std::max (maxDelay, tmpFallDelay) ;
	}
	
	valid = true ;
	return maxDelay ;
}


double ExtendedLibParser::maxRiseTransition (std::string cellName, std::map<std::string, double>& pinTrans, double outCap, bool& valid)
{
	double maxDelay = 0.0 ;
	
	std::vector<LibParserTimingInfo>::iterator timingIt ;
	
	if (pinTrans.size() != this->mapStandardLibraryCells[cellName].timingArcs.size())
	{
#ifdef DEBUG
                cout << "The number of pin input transition are not equal to the gate pins" << endl ;
#endif
		
		return 0.0 ;
	}
	
	for (timingIt = this->mapStandardLibraryCells[cellName].timingArcs.begin() ; timingIt != this->mapStandardLibraryCells[cellName].timingArcs.end() ; ++timingIt)
	{
		double inputTrans = pinTrans[(*timingIt).fromPin] ;
		double tmpFallDelay = (*timingIt).riseTransition(outCap, inputTrans, valid) ;
		
		if (!valid)
		{
#ifdef DEBUG
                        cout << "The output capacitance and/or input transition are not in the legal range" << endl ;
#endif
			return 0.0 ;
		}
		else
			maxDelay = std::max (maxDelay, tmpFallDelay) ;
	}
	
	valid = true ;
	return maxDelay ;
}

double ExtendedLibParser::getInputCapacitance(std::string cellName, std::string pinName)
{
	std::vector<LibParserPinInfo>::iterator pinIt ;
	
	for (pinIt = this->mapStandardLibraryCells[cellName].pins.begin();
             pinIt != this->mapStandardLibraryCells[cellName].pins.end();
             ++pinIt)
	{
		if ((*pinIt).name == pinName)
			return (*pinIt).capacitance ;
	}
	
	return 0.0 ;
}

double ExtendedLibParser::maxFallTransition (std::string cellName, std::map<std::string, double>& pinTrans, double outCap, bool& valid)
{
	double maxDelay = 0.0 ;
	
	std::vector<LibParserTimingInfo>::iterator timingIt ;
	
	if (pinTrans.size() != this->mapStandardLibraryCells[cellName].timingArcs.size())
	{
#ifdef DEBUG
                cout << "The number of pin input transition are not equal to the gate pins" << endl ;
#endif
		
		return 0.0 ;
	}
	
	for (timingIt = this->mapStandardLibraryCells[cellName].timingArcs.begin() ; timingIt != this->mapStandardLibraryCells[cellName].timingArcs.end() ; ++timingIt)
	{
		double inputTrans = pinTrans[(*timingIt).fromPin] ;
		double tmpFallDelay = (*timingIt).fallTransition(outCap, inputTrans, valid) ;
		
		if (!valid)
		{
#ifdef DEBUG
                        cout << "The output capacitance and/or input transition are not in the legal range" << endl ;
#endif
			return 0.0 ;
		}
		else
			maxDelay = std::max (maxDelay, tmpFallDelay) ;
	}
	
	valid = true ;
	return maxDelay ;
}


double ExtendedLibParser::findMaxAvgDelay(std::string name)
{
	std::vector<LibParserTimingInfo>::iterator timingIt ; 
	
	std::vector<LibParserPinInfo>::iterator pinIt ; 
	
	double maxCap = 0.0 ;
	for (pinIt = this->mapStandardLibraryCells[name].pins.begin(); pinIt != this->mapStandardLibraryCells[name].pins.end(); ++pinIt)
	{
		if (!(*pinIt).isInput)
			maxCap = (*pinIt).maxCapacitance ;
	}
	
	double maxValue1, maxValue2 = 0.0 ;
	for (timingIt = this->mapStandardLibraryCells[name].timingArcs.begin(); timingIt != this->mapStandardLibraryCells[name].timingArcs.end(); ++timingIt)
	{
		maxValue1 = std::max (maxValue1, (*timingIt).fallDelay.avgValue) / maxCap ; 
		maxValue2 = std::max (maxValue2, (*timingIt).riseDelay.avgValue) / maxCap ;
	}
	
#ifdef DEBUG
        cout << "Max Delay: " << std::max(maxValue1, maxValue2) ;
#endif
	return std::max(maxValue1, maxValue2) ;
}

// First Cell has lower delay and equal or lower leakage
bool ExtendedLibParser::isCover (std::string cell1, std::string cell2, int stepSize)
{
	std::vector<LibParserTimingInfo>::iterator timingItFirst, timingItSecond ;
	
	bool final = true ;
	
	for (timingItFirst = this->mapStandardLibraryCells[cell1].timingArcs.begin() ;
             timingItFirst != this->mapStandardLibraryCells[cell1].timingArcs.end() ;
             ++timingItFirst)
	{
	
		for (timingItSecond = this->mapStandardLibraryCells[cell2].timingArcs.begin() ;
                     timingItSecond != this->mapStandardLibraryCells[cell2].timingArcs.end() ;
                     ++timingItSecond)
		{
		
			if ( (*timingItSecond).fromPin != (*timingItFirst).fromPin ||
                             (*timingItSecond).toPin != (*timingItFirst).toPin )
                                continue ;
					
			//check Fall Delay
			double maxOutputCap = std::min((*timingItFirst).fallDelay.loadIndices.back() , (*timingItSecond).fallDelay.loadIndices.back()) ;
			double maxInputTrans = std::min((*timingItFirst).fallDelay.transitionIndices.back() , (*timingItSecond).fallDelay.transitionIndices.back()) ;
			
#ifdef DEBUG
                        cout << "max output capacitance: " << maxOutputCap << endl ;
                        cout << "max input transition:" << maxInputTrans << endl ;
#endif
			
			bool valid ;
			
			double outCap = (*timingItFirst).fallDelay.loadIndices.front() ;
			double inpTrans = (*timingItFirst).fallDelay.transitionIndices.front() ;
			
			double outCapStep = (double) (maxOutputCap - outCap) / (double) stepSize ;
			double inpTransStep = (double) (maxInputTrans - inpTrans) / (double) stepSize ;
			
			double tmpInpTrans = inpTrans ;
			
#ifdef DEBUG
                        cout << "first output capacitance:  " << outCap << endl ;
                        cout << "first input transition: " << inpTrans << endl ;
                        cout << "capacitance step: " << outCapStep << endl ;
                        cout << "transition step: " << inpTransStep << endl ;
#endif
			
			while ( outCap <= maxOutputCap)
			{
				inpTrans = tmpInpTrans ;
				while (inpTrans <= maxInputTrans)
				{
					double firstDelay =  (*timingItFirst).fallDelay(outCap, inpTrans, valid) ; 
					double secondDelay = (*timingItSecond).fallDelay(outCap, inpTrans, valid) ;
					
#ifdef DEBUG
                                        cout << "Fall Delay" << endl ;
                                        cout << "First Delay: " << firstDelay << endl ;
                                        cout << "Second Delay: " << secondDelay << endl ; 
#endif
					
					if ( firstDelay > secondDelay)
					{
						final = false ;
						break ;
					}	
					
					firstDelay = (*timingItFirst).riseDelay(outCap, inpTrans, valid) ;
					secondDelay = (*timingItSecond).riseDelay(outCap, inpTrans, valid) ;
					if ( firstDelay > secondDelay )
					{
						final = false ;
						break ;
					}	
					inpTrans += inpTransStep ;
#ifdef DEBUG
                                        cout << "Next transition: " << inpTrans << endl ;
#endif
				}
				
				if (!final)
					break ;
				outCap += outCapStep ;
				
#ifdef DEBUG
                                cout << "Next Output Cap: " << outCap << endl ;
#endif
			}
		}
	
	}
	
#ifdef DEBUG
        cout << "Leakage Power" << endl ;
        cout << "First Leakage: " << this->mapStandardLibraryCells[cell1].leakagePower << endl ;
        cout << "Second Leakage: " << this->mapStandardLibraryCells[cell2].leakagePower << endl ;
#endif
	if (final && this->mapStandardLibraryCells[cell1].leakagePower <= this->mapStandardLibraryCells[cell2].leakagePower)
		return true ;
	else
		return false ;
	
}


void ExtendedLibParser::pruneFootprint (std::string fpName, std::vector<std::string>& pruned)
{
	std::vector<std::string> sameFP ;
	std::vector<std::string> covered ;
 	// Fill vector with the gates which have same footprint
	this->findSameFootPrint (fpName, sameFP) ;
	
	std::vector<std::string>::iterator cellIt1, cellIt2 ;
	pruned.clear() ;
	
	for (cellIt1 = sameFP.begin() ; cellIt1 != sameFP.end() ; cellIt1++)
	{
		if (std::find(covered.begin(), covered.end(), (*cellIt1)) != covered.end())
			continue ;
		for (cellIt2 = sameFP.begin() ; cellIt2 != sameFP.end() ; cellIt2++)
		{
			if ((*cellIt1) == (*cellIt2))
				continue ;
				
			else
			{
				if ( this->isCover((*cellIt1), (*cellIt2), 10) )
				{
#ifdef DEBUG
                                        cout << (*cellIt1) << " cover " << (*cellIt2) << endl ;
#endif
					covered.push_back((*cellIt2)) ; 
				}
			}
		}
	}
	
	std::vector<std::string>::iterator it ;
	for (int i = 0 ; i < (int)covered.size() ; ++i)
	{
		it = std::find(sameFP.begin(), sameFP.end(), covered[i]) ;
		if (it != sameFP.end())
			sameFP.erase(it) ;
	}
	
	for (int i = 0 ; i < (int)sameFP.size() ; ++i)
		pruned.push_back(sameFP[i]);
}	
void ExtendedLibParser::extractAllFootPrints(std::vector<std::string>& footPrintVector)
{
	footPrintVector.clear() ;
	
	std::map<std::string, LibParserCellInfo>::iterator it ;
	
	for (it = this->mapStandardLibraryCells.begin() ; it != this->mapStandardLibraryCells.end(); ++it)
	{
		if ( std::find(footPrintVector.begin(), footPrintVector.end(), (*it).second.footprint ) == footPrintVector.end()) 
			footPrintVector.push_back((*it).second.footprint) ;
	}
}


void ExtendedLibParser::drawDelayLeakageCurve (std::string filename)
{
	std::ofstream curve (filename.c_str()) ;
	
	std::vector<std::string> footprints ;
	std::vector<std::string> cells ;
	
	this->extractAllFootPrints(footprints) ;
	curve << "Cell Name\t" << "LeakagePower\t" << "Max Delay\t" << endl ;
	for (int i = 0 ; i < (int)footprints.size(); ++i)
	{
		this->findSameFootPrint(footprints[i], cells) ;
		curve << footprints[i] << endl ;
		for (int j = 0 ; j < (int)cells.size(); ++j)
			curve << cells[j] << "\t"
                              << this->mapStandardLibraryCells[cells[j]].leakagePower << "\t"
                              << this->findMaxAvgDelay(cells[j]) << endl ;
	}
	
	
}


void ExtendedLibParser::intermediateCapPoints (LibParserLUT& timing, std::ofstream& outFile, double min, double max, std::vector<double>& transitionIndices)
{
	double midPoint1 = (max - min) / (double) 2.0  + min;
	double midPoint2 = (midPoint1 - min) / (double) 2.0 + min;
	double midPoint3 = (max - midPoint1) / (double) 2.0 + midPoint1;
	bool valid ;
	
	outFile << min << "\t" ;
	for (int j = 0 ; j < (int) transitionIndices.size() ; ++j)
	{
		outFile <<  timing(min, transitionIndices[j], valid) ;
		outFile << "\t" ;
	}
	outFile << endl ;
	
	outFile << midPoint2 << "\t" ;
	for (int j = 0 ; j < (int) transitionIndices.size() ; ++j)
	{
		outFile <<  timing(midPoint2, transitionIndices[j], valid) ;
		outFile << "\t" ;
	}
	outFile << endl ;
	
	outFile << midPoint1 << "\t" ;
	for (int j = 0 ; j < (int) transitionIndices.size() ; ++j)
	{
		outFile <<  timing(midPoint1, transitionIndices[j], valid) ;
		outFile << "\t" ;
	}
	outFile << endl ;
	
	outFile << midPoint3 << "\t" ;
	for (int j = 0 ; j < (int) transitionIndices.size() ; ++j)
	{
		outFile <<  timing(midPoint3, transitionIndices[j], valid) ;
		outFile << "\t" ;
	}
	outFile << endl ;
	
	outFile << max << "\t" ;
	for (int j = 0 ; j < (int) transitionIndices.size() ; ++j)
	{
		outFile <<  timing(max, transitionIndices[j], valid) ;
		outFile << "\t" ;
	}
	outFile << endl ;
	
}


void ExtendedLibParser::deltaCapDelay(std::string cellName, std::string fileName)
{
	std::ofstream outFile(fileName.c_str()) ;
	
	std::vector<LibParserTimingInfo>::iterator timingIt ;
	
	for (timingIt = this->mapStandardLibraryCells[cellName].timingArcs.begin() ;
             timingIt != this->mapStandardLibraryCells[cellName].timingArcs.end() ;
             ++timingIt)
	{
		outFile << (*timingIt).fromPin << " => " << (*timingIt).toPin << endl ;
		
		outFile << "--------------------Fall Delay--------------------" << endl ;
		
		outFile << "\t" ;
		for (int j = 0; j < (int)(*timingIt).fallDelay.transitionIndices.size() ; j++)
		{
			outFile << (*timingIt).fallDelay.transitionIndices[j] << "\t" ;
		}
		outFile << endl ;
		
		for (int i = 0 ; i < (int)(*timingIt).fallDelay.loadIndices.size() - 1 ; ++i)
		{
			this->intermediateCapPoints((*timingIt).fallDelay, outFile,(int)(*timingIt).fallDelay.loadIndices[i],
                                                    (int)(*timingIt).fallDelay.loadIndices[i+1], 
                                                    (*timingIt).fallDelay.transitionIndices) ;
		}
		
		outFile << "--------------------Rise Delay--------------------" << endl ;
		
		outFile << "\t" ;
		for (int j = 0; j < (int)(*timingIt).fallDelay.transitionIndices.size() ; j++)
		{
			outFile << (*timingIt).fallDelay.transitionIndices[j] << "\t" ;
		}
		outFile << endl ;
		
		
		for (int i = 0 ; i < (int)(*timingIt).riseDelay.loadIndices.size() - 1 ; ++i)
		{
			this->intermediateCapPoints((*timingIt).riseDelay, outFile,(int)(*timingIt).riseDelay.loadIndices[i],
                                                    (int)(*timingIt).riseDelay.loadIndices[i+1], 
                                                    (*timingIt).riseDelay.transitionIndices) ;
		}	
	}
}



